﻿using System;
using System.Linq;
using System.Reflection;
using System.Data;
using System.Collections;

namespace DBCore
{
    /// <summary>
    /// 实体基类
    /// </summary>
    [Serializable()]
    public class Entity
    {
        public static string[] EnumerableNamePropertys = new string[] { "EntityName", "SqlName" };
        public static string[] EnumerableValuePropertys = new string[] { "Value" };
        public Entity() { }
        public Entity(DataRow row)
        {
            Extend(row);
        }
        public Entity(object obj)
        {
            Extend(obj);
        }
        public Entity(IEnumerable list)
        {
            Extend(list);
        }

        public void Extend(DataRow row)
        {
            var ps = IOC.TypePropertyInfos[this.GetType()];
            foreach (PropertyInfo p in ps)
            {
                if (row.Table.Columns.Contains(Getcolumnname(p)))
                {
                    var val = row[Getcolumnname(p)];
                    if (val == DBNull.Value)
                    {
                        val = null;
                    }
                    p.SetValue(this, val, null);
                }
            }
        }

        public void Extend(object obj)
        {
            if (obj != null)
            {
                var ps = IOC.TypePropertyInfos[this.GetType()];
                foreach (PropertyInfo p in ps)
                {
                    var val = obj.Get(p.Name);
                    if (val != null)
                    {
                        p.SetValue(this, val, null);
                    }
                }
            }
        }

        public void Extend(IEnumerable list)
        {
            var ps = IOC.TypePropertyInfos[this.GetType()];
            var coll = list.GetEnumerator();
            while (coll.MoveNext())
            {
                var o = coll.Current;
                PropertyInfo p = null;
                foreach (var sname in EnumerableNamePropertys)
                {
                    var oname = o.Get(sname);
                    if (oname != null && oname.ToString() != "" && ps.ToList().Exists(pro => pro.Name.ToLower() == oname.ToString().ToLower()))
                    {
                        p = ps.ToList().Find(pro => pro.Name.ToLower() == oname.ToString().ToLower());
                        break;
                    }
                }
                var value = EnumerableValuePropertys.Select(o.Get).FirstOrDefault(ovalue => ovalue != null);
                if (p != null && value != null)
                {
                    if (!p.PropertyType.IsValueType)
                    {
                        p.SetValue(this, Convert.ChangeType(value, p.PropertyType), null);
                    }
                    else
                    {
                        if (p.PropertyType.IsGenericType)
                        {
                            p.SetValue(this, Convert.ChangeType(value, p.PropertyType.GetGenericArguments()[0]), null);
                        }
                        else
                        {
                            var val = Convert.ChangeType(value, p.PropertyType);
                            p.SetValue(this, val, null);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 获得列名
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>
        private string Getcolumnname(PropertyInfo property)
        {
            var propertyattrs = IOC.EntityPropertyAttributes[this.GetType()];
            if (propertyattrs.ContainsKey(property))
            {
                return propertyattrs[property].SqlName;
            }
            else
            {
                return property.Name;
            }
        }
    }

    public enum EntityType
    {
        Table = 0,
        InputProd = 1,
        OutPutProd = 2
    }
}
